/*  File Name	: Reactor.cpp
 *  Author		: Pang Jiacai
 *	 E-mail		: 823960168@qq.com
 *  Created on	: 2012-2-2
 *  Description:
 */

#include "Reactor.h"


Reactor::Reactor(ReactorImpl *impl):impl_(impl)
{

}

Reactor::~Reactor()
{

}

Reactor *Reactor::instance_ =NULL;
RT_MUTEX Reactor::rt_mutex_;
Reactor *Reactor::instance(void)
{
	if(NULL==instance_)
	{
		LockGuardReturn(RT_MUTEX,lock,rt_mutex_,NULL);
		if(NULL==instance_)
		{
			instance_ = new Reactor();
		}
	}
	return instance_;
}

int Reactor::open(int handle_size,int timer_heap_size,SignalHanlder *sh,bool only_timer)
{
	return this->implement()->open(handle_size,timer_heap_size,sh,only_timer);
}

int Reactor::register_handler(int handle,EventHandler *eh,ReactorMask mask)
{
	return this->implement()->register_handler(handle,eh,mask);
}

/**
 * this function will call EventHandler::handle_close
 * so,don't invoke it in EventHandler::handle_close
 */
int Reactor::remove_handler(int handle,EventHandler *eh,ReactorMask mask)
{
	return this->implement()->remove_handler(handle,eh,mask);
}

int Reactor::register_signal(int signum,EventHandler *eh,
		bool replace_old,EventHandler *old_sh)
{
	return this->implement()->register_signal(signum,eh,replace_old,old_sh);
}

int Reactor::remove_signal(int signum,EventHandler *eh)
{
	return this->implement()->remove_signal(signum,eh);
}

long Reactor::schudle_timer(EventHandler *eh,TimeValue delay,TimeValue interval)
{
	return this->implement()->schudle_timer(eh,delay,interval);
}

int Reactor::suspend_timer(long  timer_id)
{
	return this->implement()->suspend_timer(timer_id);
}

int Reactor::cancel_timer(long  timer_id)
{
	return this->implement()->cancel_timer(timer_id);
}

int Reactor::refresh_timer(long  timer_id,TimeValue new_time)
{
	return this->implement()->refresh_timer(timer_id,new_time);
}

RT_MUTEX &Reactor::lock(void)
{
	return this->implement()->lock();
}

int Reactor::run_reactor_loop(int timeout)
{
	//check reactor run status
	if(this->run_status()==1)
	{
		return 0;
	}

	//set running
	this->implement()->run_status(1);

	int result= 0;
	while(true)
	{
		//LOG((DEBUG_LOG,"Reactor::run_reactor_loop[%d][%d]",this->run_status(),timeout));
		result = this->handle_events(timeout);
		if(this->run_status()==2)
		{
			LOG((INFO_LOG,"Reactor::run_reactor_loop-->exit"));
			return 0;
		}
		else if(result >= 0)
		{
			continue;
		}
		else
		{
			return result;
		}
	}
	return 0;
}

int Reactor::end_reactor_loop()
{
	this->implement()->run_status(2);
	return 0;
}

ReactorImpl* Reactor::implement()
{
	return this->impl_;
}

//reactor run status,1:start 2:stop
int Reactor::run_status(void)
{
	return this->implement()->get_run_status();
}

void Reactor::implement(ReactorImpl *impl)
{
	if(NULL!=impl)
	{
		this->impl_ = impl;
	}
}

//1:select  2: epoll
int Reactor::reactor_type(void) const
{
	return this->impl_->reactor_type();
}

int Reactor::handle_events(int timeout)
{
	return this->implement()->handle_events(timeout);
}
